Le dichiarazioni preparate non sfuggono a nulla. Quando prepari un'istruzione, la tua query viene precompilata, in modo che abbia bisogno solo dei segnaposto ( ? ) da compilare. Poiché non è possibile modificare l'SQL della query precompilata, non è necessario l'escape.
Per risolvere questo problema, esci da % e _ manualmente.
Aggiunto:
Un po' di buon senso:nel tuo caso, quando un utente inserisce % in una casella di ricerca, il tuo $search la variabile contiene la stringa %%% . Come farebbe MySQL a sapere, quale % dovrebbe scappare e quale dovrebbe lasciare in pace?