It's not that the node is non-destroyable. It just exists at a level of the SceneTree that isn't freed when scenes change. It's the same concept as a variable outside the scope of a function.
The singletons and the active scene get added to the root viewport. To see this in action, create a singleton and do the following:
for child in get_tree().get_root().get_children():
So if you'd like to scope things in the same fashion in code you could manage the children manually by retrieving the root viewport. Then applying the methods
var root = get_tree().get_root()