Code-Golf Ascii Art Mini-Golf
Javascript (ES6) - 651 bytes

G=s=&gt;{Q='\\';S=[[]];n=L=1;s.split(N='\n').map(t=&gt;{j=S[L++]=[];l=t.length;n=n&gt;l?n:l;k=1;t.split('').map(T=&gt;{j[k++]=T})});S[O=L++]=[];n++;for(r=0;r&lt;L;r++)for(c=0;c&lt;=n;c++){v=S[r][c];if(!v)S[r][c]=' ';if(v=='.'){x=c;y=r}if(v=='o'){X=c;Y=r}}f=M=&gt;{J=M?'.':'o';K=M?'o':'.';R=0;for(D=0;1;D++){R=D&amp;4;D=D&amp;3;c=e=D;g=M?X:x;h=M?Y:y;while(c!=K){c=S[h+=[-1,0,1,0][e]][g+=[0,1,0,-1][e]];e=c=='/'?(B=c,e^1):c==Q?(B=c,3-e):e;E=h*(h-O)?g*(g-n)?0:2:1;if(R&amp;&amp;c==' '){S[h][g]=Q;R=D=0;c=K}if(c==J||E){E&amp;&amp;(S[h][g]=(E+M)%2?Q:'/');H=M?E?H:(e+2)&amp;3:D;return}}}};f(0);f(1);S[0][0]=S[O][n]='/';S[0][n]=S[O][0]=Q;return['up','right','down','left'][H]+N+S.map(t=&gt;t.join('')).join(N)}


Creates a function G that accepts a string (golf course) as input and returns the requested putting solution. The input string may or may not have leading lines, trailing lines, and trailing whitespace. The output will not have leading or trailing whitespace.

Expanded code is:

G = s =&gt; {
    Q = '\\';
    S = [[]];
    n = L = 1;
    s.split( N = '\n' ).map( t =&gt; {
        j = S[L++] = [];
        l = t.length;
        n = n &gt; l ? n : l;
        k = 1;
        t.split('').map( T =&gt; {
            j[k++] = T;
        } );
    } );
    S[O = L++] = [];
    n++;
    for( r = 0; r &lt; L; r++ )
        for( c = 0; c &lt;= n; c++ ) {
            v = S[r][c];
            if( !v )
                S[r][c] = ' ';
            if( v == '.' ) {
                x = c;
                y = r;
            }
            if( v == 'o' ) {
                X = c;
                Y = r;
            }
        }
    f = M =&gt; {
        J = M ? '.' : 'o';
        K = M ? 'o' : '.';
        R = 0;
        for( D = 0; 1; D++ ) {
            R = D &amp; 4;
            D = D &amp; 3;
            c = e = D;
            g = M ? X : x;
            h = M ? Y : y;
            while( c != K ) {
                c = S[h += [-1,0,1,0][e]][g += [0,1,0,-1][e]];
                e = c == '/' ? (B=c,e^1) : c == Q ? (B=c,3-e) : e;
                E = h*(h-O) ? g*(g-n) ? 0 : 2 : 1;
                if( R &amp;&amp; c == ' ' ) {
                    S[h][g] = B;
                    R = D = 0;
                    c = K;
                }
                if( c == J || E ) {
                    E &amp;&amp; (S[h][g] = (E+M)%2 ? Q : '/');
                    H = M ? E ? H : (e+2)&amp;3 : D;
                    return;
                }
            }
        }
    };
    f(0);
    f(1);
    S[0][0] = S[O][n] = '/';
    S[0][n] = S[O][0] = Q;
    return ['up','right','down','left'][H] + N + S.map( t =&gt; t.join('') ).join( N );
}


The solver operates on the premise that any path from the ball (hole) will either


lead back to the ball (hole) again
lead to the hole (ball)
exit the course


We trace the ball's path in all four directions. If we find case 3, the problem is solved. If we find case 2, we mark the ball's exit location. If all four directions result in case 1, we convert the first non-bumper space along any trajectory to a bumper (if the problem is solvable, such a space is always guaranteed to exist) and try again. The bumper we convert to will have the same type as the last bumper our trajectory encountered*. If the ball is still stuck in a loop, we repeat the process as many times as needed. If the problem is solvable, this procedure is guaranteed to eventually lead to outcome 2 or 3.

(*Note that if we simply convert to a fixed bumper [say, \], there exist extremely contrived but nevertheless possible cases where a solution exists but we will fail to find it.)

We perform a similar trace from the hole, leading to either outcome 2 or outcome 3.

If both the ball trace and hole trace result in outcome 2, we place bumpers on the periphery of the course that link the two exit points (in fact, these periphery bumpers are placed regardless of the trace outcomes, to shorten the code). This completes the solution.

Test Cases and Outputs

In

   /   \   / \ /\    
   \\      /    \  \ 
       /     / o   / 
   /   \       /     
   \   .  \  \    \\ 
       /  /     \ \  
       \          /  
           \      /  
 \ /\     /  \/  //\


Out

right
/   /               \
   /   \   / \ /\    
   \\      /    \  \ 
       /     / o   / 
   /   \       /     
   \   .  \  \    \\ 
       /  /     \ \  
       \          / /
           \      /  
 \ /\     /  \/  //\ 
\                   /


In

  / \   / /    /  \    / \  /  \\ /
\   \ /  \  // \    \   /   /\   \
/ \   // \  //   \ \   \ /  / \\ \
 \  / \    /   \  \  / / \\ / /  //
/ /   /\ \\ //  / \   /  \ / \\ \ \
\   \  \ \ // \ /  /    \ \  /  / /
/ \ /   /  / \     / \ /\   /  \  /
\ /\  //\   .\  \ \ //\ /  \  / \ /
/ \/ \ /\ //\   /   \   / o// \ / \
/   / \    / \ / \\ / \   / \   \ \
/ /   / \  / \ //   \    / \/  /\/
   / \   / \  /   \\  / \    /\ / \
/ \/   \   /   \/  \   /  \    /\\
/ /\\ //\  / \  /\ /\   /  / \ / \/


Out

left
/                                   \
   / \   / /    /  \    / \  /  \\ / 
 \   \ /  \  // \    \   /   /\   \  
 / \   // \  //   \ \   \ /  / \\ \  
  \  / \    /   \  \  / / \\ / /  // 
 / /   /\ \\ //  / \   /  \ / \\ \ \ 
 \   \  \ \ // \ /  /    \ \  /  / / 
 / \ /   /  / \     / \ /\   /  \  / 
 \ /\  //\   .\  \ \ //\ /  \  / \ / 
 / \/ \ /\ //\   /   \   / o// \ / \ 
 /   / \    / \ / \\ / \   / \   \ \ 
 / /   / \  / \ //   \    / \/  /\/  
    / \   / \  /   \\  / \    /\ / \ 
 / \/   \   /   \/  \   /  \    /\\  
 / /\\ //\  / \  /\ /\   /  / \ / \/ 
\         \                         /


In

/\/ \      
\  \ \     
 \ \\ \   o
  \ .\ \   
   \ / /   
    \ /    


Out

down
/   \      /\
 /\/\\       
 \ \\ \      
  \ \\ \   o 
   \ .\ \    
    \ / /    
     \ /     
\           /