There are some decent answers here, but I find most of them lacking something. Some have said "its just experience," which isn't very helpful and I don't agree with.
There are some suggestions about doing exercises and small programs, which will help you remember the patterns, but seems like rote memorization, which isn't as useful as really understanding design patterns. Its easy to understand patterns in isolation, but harder to apply them within an old, crufty program.
The patterns I've seen mentioned so far are Singleton and Factory, which are probably two of the more harmful and misleading design patterns.
Anyways, my answer, from my personal experience:
Test Driven Design: This almost forces to you use new patterns out of necessity. The object collaboration and composition patterns it forces you to use can really shift your understanding and view of some patterns. Patterns like Visitor, Strategy, Adapter, and Bridge become a lot more clear.
New Projects: With new projects, you can use any patterns in any way you choose. A new project lets you analyze your problem space and figure out what patterns might be appropriate and why. This heavily relies on your creativity and ability to think about future uses and reuses of your project.
Existing Projects: Old projects will naturally need some redesign, and if you poke around, you'll be able to see where patterns can be used. These usually require surgical operations, but thats a fun challenge. You need to avoid the urge maintain the status quo, to keep doing things "how they've always been done." Part of the problem you may run into is that you can't use a pattern because it will break everything. In that case, you're most likely a) using the wrong pattern or b) not limiting the scope of the pattern enough. When you find how a pattern can easily slip into existing code, then you're beginning to really understand the pattern.
Code Duplication: Any time you see the same function or routine used more than a couple times in similar contexts is probably a place some sort of pattern could have been used. If you have an old project with a lot of glue javascript, you'll see lots of copy-paste duplication you can probably abstract out. This is also a classic "code smell" that others have mentioned.
Your own laziness: Part of the purpose of design patterns to to provide flexibility. This flexibility pays off in the long run when you have an odd request. You may end up writing a fair amount of code to glue the pieces together, but thats better than having to set up global flags and pass magic values to identify the use case. I'd like to clarify that I mean laziness in the sense of ultimate laziness. It may be easier to hack something together, but you still have to test, release, and maintain it, which is a helluva lot more work than writing it.
An example: While writing a data import script, I would log information to a file because thats what the final version needed to do. This required me to re-tail the file every invocation. How frustrating. Wouldn't it be nice if I could log to the console during dev with the flip of a switch, without having to put hacks in the code? Enter the Facade pattern and Strategy patterns.
Using What You Don't Know: By this I mean, if you don't know the requirements fully, you're forced to abstract it out so that you can easily adapt to a change in them. "Requirements" doesn't just mean a crappy spec your client handed you, it also means your own uncertainties as you write your code. If you find yourself blocking on an issue, abstract it out and stub it. Now, suddenly, you can stub it out with any behavior, be it for testing, development, or lucid requirements.
Experience: Others have said this as a generality, so I'd like to clarify. I think experience - real wisdom and knowledge - means understanding whats going on "behind the scenes." That is to say, what the goals are rather than the symptoms of the problem. Experience is the intuitive equivalent of the critical thinking I mention below.
Creativity and Critical Thinking: This is the only one you need really, but its not very helpful to say "think better" :). I've found a lot of developers are too pragmatic - "we'll just solve this specific case and be done with it." Iterate that a few times and you end up with the maintenance nightmares we all complain about. So, solve the generalized, "n - 1" case. That doesn't mean you need to look on from the heavens and try to write "100% clean, pure" code in an attempt to solve every imaginable situation, but that you should step back once and try and design for that. This ties into above.
Anyways, I'll give some examples, I hope these are helpful.
Its easy to use the Singleton patterns - "I have one datastore, and I want to make access to it easy" - but thats shortsighted. How do you isolate and easily test pieces that depend on the datastore? What if there are multiple datastores, one for reading, one for writing, one for searching, and one for historical data? Think about your ease of development, qa, and release process. What happens when you need to selectively disable or change the behavior of a component?
Another example is users: its easy to have a Singleton $user object which represents the currently logged in user. What happens when you need to sudo as another user, or do operations within the context of another user, such as timezone conversion or dealing with preferences?
Say you have some sort workflow you walk through as users update objects. A new requirement needs to make external service calls and users must update the object correctly. If something goes wrong, then you have to go back to before this workflow. Other updates may occur during this workflow. Conceptually, this is similar to the Command pattern, perhaps with a bit of Strategy mixed in, but its not so apparent because those definitions don't include "workflow" or "concurrent updates," and can become further muddled if the architecture isn't friendly to "undo"