The service finder is better than the singleton. The well-known instance (a pointer a static global pointer initialized during program startup that points to the current version) is better than a singleton. Even the global static variable that delays application startup is better than the singleton in nearly every case.
In all these cases you can still have an instance that everybody uses, you can still have your hidden background dependency that no code acknowledges. But you can do it without the singleton.
Just because you only have one right now does not mean you should prohibit the option to only have one ever.
It seems the common example people give of a "good" singleton is a logging system. But even there, what if I am building and debugging a system and want my own private logger that points to a different logging destination for my own debugging purposes? If it is a singleton, I am forbidden from it.
Having a single instance of something is not a problem. There are many objects out there where you only ever need a single instance. However, that is radically different from the Singleton. The Singleton means you can only have one instance ever, and are forbidden from creating another. A Singleton means you are forbidden from ever creating more than a single instance; it follows that you are also forbidden from copying it, from cloning it, from abstracting it, from subclassing it, from testing it (you cannot use mock objects), from parallelizing it, and so on.
Singleton != happening to only have a single instance. Singleton means much stricter requirements.
There are several development issues that need to be overcome, they can be addressed without the Singleton problem.
Shared state is a difficult problem. There are situations where multiple systems need to know about details from other systems, sharing their state. This should be minimized by using accessors and mutators rather than directly modifying values, by using event listeners that get notified when values are changed so they can respond and update, and by other methods. This is a case where you tend to need only a single instance that maintains the state, but that is very different from a Singleton. Remember that happening to have only a single instance != Singleton.
It is common to have a collection of well-known objects. For example, you may have a structure configured at the start of the game containing pointers to the simulation, to the renderer, to resource stores, to game state, and to the application logger. These should still not be implemented as a singleton where there can only be one instance ever, but instead as a central location for discovering the shared information.
It is common for dependencies to be changed at runtime. You might replace entire systems like dropping in a new network controller when you connect or disconnect from servers. Some beginners think this means you need a Singleton class to guarantee that only one item is active. Instead you can use a well-known instance that serves as a redirector to the currently active instance.
Trying to stay on topic, an example could be a global instance of a structure something like this:
struct GloballySharedObjects {
Simulator* simulator = NULL;
Renderer* renderer = NULL;
NetworkCore* network = NULL;
MeshStore* meshStore = NULL;
TextureStore* texStore = NULL;
AudioStore* audioStore = NULL;
MusicStore* musicStore = NULL;
ILogger* log = NULL;
...
};
Elsewhere:
// Global object so we can share state. The hidden dependencies should be avoided if possible, but still better than singleton.
GloballySharedObjects gs;
Then you can build all your parts for resource management: A store, a cache, a loader, and proxy objects. They can be swapped out as needed, all without a singleton.