Where is the Arrow Pointing?
JavaScript (ES6), 195 245 231 242 246 250
Edit4 Now, a single recursive function. Probably can't be golfed more
Edit3 Test for straight line and test for arrowhead merged in T function, S  and H functions removed.
Edit2 Revised and longer :( after this this clarification
Edit Small improvements, cutting some char here and there, waiting for CJammers to step in
Test running the snippet below in an EcmaScript 6 compliant browser. (works on Firefox. Chrome still missing the spread operator ...)


f=(s,p=s[I='indexOf']`S`,w=m=[o=~s[I]`
`,1,-o,-1],q,v,r)=&gt;m.some((d,i)=&gt;{for(v=w,q=p;r=s[q+=d],r=='|-'[i&amp;1];)v='+';return r=r==v?f(s,q,v):/\w/.test(r=s[q+m['^&gt;V&lt;'[I](r)]])&amp;&amp;r},s=[...s],s[p]=0)&amp;&amp;r


// Less golfed
// U: recursive scan function
U = (s, // input string or array
     p = s.indexOf`S`, // current position, defult to position of S into string (at first call)
     w = // char to compare looking for a '+', at first call default to garbage as you can't follow '+' near 'S'
       m = [// m, global, offset array form movements. 
         o = ~s.indexOf`\n`, // o, global, row line +1 (negated)
         1, -o, -1], // complete the values of m array
     // m and o are assigned again and again at each recursive call, but that is harmless
     // params working as local variables as the function is recursive
     q,v,r) =&gt; 
{
   s = [...s]; //convert to array, as I have to modify it while scanning
     //the conversion is done again and again at each recursive call, but that is harmless
   s[p] = 0; // make s[p] invalid to avoid bouncing back and forth
  
   m.some( // for each direction, stop if endpoint found
      (d,i ) =&gt; {
        q = p; // start at current position, then will add the offset relative to current direction
        v = w; // for each direction, assign the starting value that can be '+' or garbage at first call
        // compare char at next position with the expected char based on direction (- for horiz, | for vertical)
        // in m array, values at even positon are vertical movements, odds are horizontal
        while (s[q+=d] == '|-'[i&amp;1]) // while straight direction, follow it until it ends
          v = '+'; // from now on '+' is allowed
        r = s[q];
        if (r == v) // check if found a '+'
          r = U(s, q, v) // recursive call to check all directions from current position
        else
        {
          r = s[q + m['^&gt;V&lt;'.indexOf(r)]], // pointed char in p (if arrowhead, else will return undefined)
          r = /\w/.test(r) &amp;&amp; r // if alphanumeric, then we found our result - else r = false
        }  
        return r; // returning r to .some; if r is truthy, the .some function will stop
      }
   ) 
   return r; // result if found, else undefined or null
}

// TEST
out=x=&gt;O.innerHTML+=x.replace(/&lt;/g,'&amp;#60;')+'\n'

// Using explicit newlines '\n' to ensure the padding to a rectangle
;[
 ['z&lt;+S-+-&gt;a','a'] 
,['a&lt;-+S&gt;b','b']
,['S-+\n  |\n  V\n  a','a']
,['a S      s\n  |      |\n  V      V\n  b      c  ','b']
,['S-----+  \n|     +-^  \n+---+-&gt;B \n    +---^','B']
,['d s&lt;+S+--V\n    |||  Q\n    -++    ','Q']
,['d s-+   +-S  +--+\n    +--&gt;b |  |  |\n     |  | +--+  |\n     +--+ A&lt;----+  ','A']
,['S-----+   \n|     +-^ \n+---+-&gt;B  \n    +---^ ','B']
].forEach(t=&gt;{
  r=f(t[0])
  k=t[1]
  out('Test '+(r==k?'OK':'Fail')+'\n'+t[0]+'\nResult: '+ r +'\nCheck: '+k+'\n')
})
&lt;pre id=O&gt;&lt;/pre&gt;