Write code for the application you want, not the set of all applications you might hypothetically want someday. Incur the cost of new features after you decide you want them, not before.
As with any software engineering guideline, there are exceptions. E.g. Java-style loggers are so ubiqitous and "not that mutable", that it's generally good for them to be global.
Edit: also from experience, suddenly wanting two of something where before there was only one, is not that uncommon.
If you plan to "virtualise" stuff later, instantiation is certainly the way.
Also, if you have so many globals that passing them around as parameters / instance variables becomes truly tedious, that can be a valuable signal that the program is poorly structured.
Of course, none of this matters in small codebases, as long as they stay small.
I'm developing a game in Unity, and the programming culture around it encourages globals and singletons to an unhealthy degree. I pushed back against them heavily in our project. As a result, it was very easy to add a previously unplanned split-screen mode one day, thanks to the codebase (e.g. the UI and input modules) not assuming that there's only ever one local player.