There are two answers you get when you ask what characterizes an outstanding programmer:
Other Programmers: Knows programming languages into the smallest details, and can do amazing things with it where you pause and say: “This is possible?”
Normal People: Solves problems using software in such a way that it is now much easier and more enjoyable to deal with them.
This is a problem when you ask other programmers what you should be learning to become great. You need a good understanding of your tools so that you know what is possible, and which approaches are cost effective. But this is only the basis which you use to solve actual problems, and you need additional skills on top of pure programming to succeed:
Software Engineering On top of programming languages, you need to know about algorithms, to basically know how much various approaches cost and to have an idea how your solution will scale when used with more data. And of course the basics to keep your projects sufficiently organized, especially version control, but also project documentation, and some skills in estimation.
Domain Knowledge You need to learn enough about the problem so that you can understand what people are trying to achieve, what parts can be automated, and how you ensure that people will enjoy using your solution.
Communication Skills Most interesting problems can no longer be solved by a single person, you will have multiple people working on it, and you need to know how you can work effectively together.
Design Skills If your solution is not infrastructure plumbing, its success depends greatly on how easy and accurately it can be used by your customers. Most of design is not making it aesthetically pleasing, but providing an information flow and model that the user can work successfully with.