Does using remove_child() actually delete the children or does it keep them in memory? And does keeping them in memory actually lag?
It does not. Call node.qeue_free() to delete them.
for i in get_children():
add_child(i) (Doesn't work!)
that code is broken. you are getting children from a tree, then trying to each child to the node already parenting them.
In the case of what you are trying to accomplish, remove the nodes you wish to keep from their ancestors, if you intend to delete parts 'above' them.
I might suggest you create your scenes in the following way:
one-scene contains the 'pure' low cost world element such as a rock model which contains a call that instances to itself a child scene of all the 'extras' you want when the player is near.
then all you have to do is add a function to remove the 'extras' with remove_child(extras) and extras.queue.free()
when the player is proximate, use another function to instance the extras back on your rock (or tree etc)