RewriteRule ^([^/]+)(/([^/]+))? pages.php?PAGE=$1&LINK=$3 [L]
The "problem" with this is that it will also match a request for /john-smith (the 2nd group is optional), but rewrites the request to pages.php?PAGE=john-smith&LINK=, instead of pages.php?LINK=john-smith as required. For this you will need a separate rule. It also matches /profile/john-smith/anything, discarding /anything but still rewrites the request (a many to one relationship) which potentially opens your site up to spammers.
Assuming you are not allowing dots (.) in the URL path segments (as per your examples) then there's no need to check that the request does not map to a file. eg. a request for /profile/john-smith could never map to file if your files all have file extensions, so the filesystem check is redundant.
Try the following instead:
# Rewrite exactly one path segment
# eg. /john-smith to pages.php?LINK=john-smith
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)$ pages.php?LINK=$1 [L]
# Rewrite exactly two path segments
# eg. /profile/john-smith to pages.php?PAGE=profile&LINK=john-smith
RewriteCond %{REQUEST_URI} !^/pages/ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/.]+)/([^/.]+)$ pages.php?PAGE=$1&LINK=$2 [L]
The NC flag on the preceding RewriteCond directive is probably redundant.
([^/.]+) - I've changed the capturing subpattern to also exclude dots. And the second rule matches exactly two path segments, not one or two path segments, as in your example.