Programming is about work
I think the easiest way to answer this is to understand the progress OOP has made over the years. Everything done in OOP (and most programming paradigms, for that matter) is modeled around needing work done.
Every time a method is called, the caller is saying "I don't know how to do this work, but you do know how, so you do it for me."
This presented a difficulty: what happens when the called method generally knows how to do the work, but not always? We needed a way to communicate "I wanted to help you, I really did, but I just can't do that."
An early methodology to communicate this was to simply return a "garbage" value. Maybe you expect an positive integer, so the called method returns a negative number. Another way to accomplish this was to set an error value somewhere. Unfortunately, both ways resulted in boilerplate let-me-check-over-here-to-make-sure-everything's-kosher code. As things grow more complicated, this system falls apart (or must be very carefully managed).
An Exceptional Analogy
Let's say you have a carpenter, a plumber, and an electrician. You want to plumber to fix your sink, so he takes a look at it. It's not very useful if he tells only you, "Sorry, I can't fix it. It's broken." Hell, it's even worse if he were to take a look, leave, and mail you a letter saying he couldn't fix it. Now you have to check your mail before you even know he didn't do what you wanted.
What you would prefer is to have him tell you, "Look, I couldn't fix it because it seems like your pump isn't working."
With this information, you can conclude you want the electrician to take a look at the problem. Perhaps the electrician will find something related to carpenter, and you'll need to have the carpenter fix it.
Heck, you might not even know you need an electrician, you might not know who you need. You're just middle-management in a home repair business, and your focus is plumbing. So you tell you're boss about the problem, and then he tells the electrician to fix it.
This is what exceptions are modeling: complex failure modes in a decoupled fashion. The plumber doesn't need to know about electrician- he doesn't even need to know that someone up the chain can fix the problem. He just reports on the problem he encountered.
So... an anti-pattern?
Ok, so understanding the point of exceptions is the first step. The next is to understand what an anti-pattern is.
To qualify as an anti-pattern, it needs to
- solve the problem
- have definitively negative consequences
The first point is easily met- the system worked, right?
The second point is stickier. The primary reason for using exceptions as normal control flow is bad is because that's not their purpose. Any given piece of functionality in a program should have a relatively clear purpose, and co-opting that purpose leads to unnecessary confusion.
But that's not definitive harm. It's a poor way to do things, and weird, but an anti-pattern? No. Just... odd.