The name is case sensitive and you need to be sure of your naming convention, also, the engine can change the name if is in conflict with a sibling, if you queue free a ball and add another, the second may change the name if is added before the other is completely removed.
More, if you add a new type of ball and the node is called, Ball2, you will have to rename it or change the detection or other messy stuff.
Adding all the balls to the "ball" group, you only need to check if
get_nodes_in_group("ball") size is >0 and work with the 0 index, all that independent of the node name, if it is in group ball then it is a ball (even if the node is a brick).
That is independent of the scene too, you can change the root name, create a different scene, and the code will keep working for the group "ball"
The scene instancing is the common way, depends much on the design and your style how to use it, if you prefer to delete nodes and re-instance them or just remove from tree and re-add.
But making scenes for every object or turning branches into scenes is a strong point of Godot.
The way to detect the borders is not bad, I prefer to have local game data on the scene root too than to use of globals/autoloads.
For the detection method, later you can try using Area2D (there are many shapes for different uses), VisibilityNotifier is useful too to detect things that go off screen.
In the end, everything is mostly preference, style and design and Godot allows many good approaches for the same thing.