How to give a pattern for new line in grep? New line at beginning, new line at end. Not the regular expression way. Something like \\n.
As for the workaround (without using non-portable -P), you can temporary replace a new-line character with the different one and change it back, e.g.:
grep -o "_foo_" <(paste -sd_ file) | tr -d '_'
Basically it's looking for exact match _foo_ where _ means \n (so __ = \n\n). You don't have to translate it back by tr '_' '\n', as each pattern would be printed in the new line anyway, so removing _ is enough.