I believe Stow can fix everything except #2 [1], although I haven't actually used it before. But it's also easy to create your own "garbage collector" that cleans up dangling symlinks in your home directory.
All you need to do is to keep track of symlinks you've installed with your setup script. This can be done by creating a symlink to the symlink you've installed, which acts as a "GC root." The next time you run the setup script, it would check those "GC roots" to see if they point to a valid file and remove any dangling symlinks.
This is the approach I take for my own dotfiles. I seriously considered using Stow or the bare git approach before, but I decided against it because setting up my dotfiles involved more than just installing symlinks. I had to be able to download files (e.g., vim-plug), clone git repositories, change file permissions, and maintain files that's not meant to be linked into the home directory. I found the flexibility of a custom shell script most fit for my needs.
All you need to do is to keep track of symlinks you've installed with your setup script. This can be done by creating a symlink to the symlink you've installed, which acts as a "GC root." The next time you run the setup script, it would check those "GC roots" to see if they point to a valid file and remove any dangling symlinks.
This is the approach I take for my own dotfiles. I seriously considered using Stow or the bare git approach before, but I decided against it because setting up my dotfiles involved more than just installing symlinks. I had to be able to download files (e.g., vim-plug), clone git repositories, change file permissions, and maintain files that's not meant to be linked into the home directory. I found the flexibility of a custom shell script most fit for my needs.
[1]: The "Deleting Packages" section in https://linux.die.net/man/8/stow