Guide the Alphabet

JavaScript (ES6), 108 107 94 87 bytes

Saved a whopping 13 bytes, thanks to Titus!
Saved 7 more bytes, thanks to edc65!

let f =

a=>[i=9,...a].map(d=>r[p+=(d+=d>3)*9-d%3*8-28]=(++i).toString(36),r=[],p=646)&&r.join``

console.log(f([4,7,1,6,6,6,0,3,1]));

How it works

The formula (d += d > 3) * 9 - d % 3 * 8 - 28 translates the directions 0..7 into the following offsets:

0   1   2       -28 -27 -26
3   x   4  -->   -1  x   +1
5   6   7       +26 +27 +28

We use these offsets to move the pointer p into the one-dimensional array r and write the letters at the resulting positions.

We iterate on [i = 9, ...a] rather than just a in order to insert the starting letter 'a'. Because we initialize i to 9 at the same time, we introduce a special offset of 54 (the result of the above formula for d = 9). After the first iteration, p equals 646 + 54 = 700, which leaves just enough space to support up to 25 moves to North-West: 25 * -28 = -700. That's why p is initialized to 646.

Then we just have to join the array to get our final string. Undefined values in between letters are simply ignored by join().


MATL, 64 58 57 50 46 40 37 36 35 30 bytes

O'!":<TUV '59-G)hYsIH$6#u64+c!

Try it at MATL Online

Explanation

O           % Push the number 0 to the stack
'!":<TUV '  % String literal
59-         % Converts this string literal into [-26 -25 -1 1 25 26 27 -27]. These
            % are deltas for the linear indexes into the matrix corresponding to each
            % of the directions. Note that the -27 is at the end since a 0 index wraps
            % around to the end
i)          % Grab the input and use it to index into the delta array 
h           % Horizontally concatenate this with the 0 (our starting point)
Ys          % Take the cumulative sum to get the absolute linear index (location) of
            % each successive letter
IH$6#u      % Find the index of the last (sorted) occurrence of each location
64+         % Add 64 to this index to create ASCII codes
c!          % Convert to character, transpose, and display

Octave, 145 138 131 123 105 103 90 87 85 bytes

@(a){[~,k]=unique(cumsum([1 fix((z=a+(a>3))/3);1 mod(z,3)]'-1),'rows');[k'+64 '']}{2}

Try It Online

Thanks to Suever 2 bytes saved!

Previous answer 103 bytes:

@(a)[nonzeros(accumarray(cumsum([1 fix((z=a+(a>3))/3);1 mod(z,3)]'-1)+30,65:nnz(++a)+65,[],@max)')' '']

Try It Online!

First try 145 byts

@(a){[x y]=find(~impad(1,1,1));c=cumsum([0 0;([y x]-2)(++a,:)]);c=c-min(c)+1;n=nnz(a);[nonzeros(sparse(c(:,1),c(:,2),65:n+65,'unique')')' '']}{5}

Some Explanations

@(a){
    [x y]=find([1 0 1]|[1;0;1]);                            %generate 2d coordinates corresponding to 1d input indices
    XY = [y x]-2;
    c=cumsum([0 0;XY(++a,:)]);                              %cumulative sum of coordinates to find position of characters
    c=c-min(c)+1;n=nnz(a);
    [nonzeros(sparse(c(:,1),c(:,2),65:n+65,'unique')')' ''] %using sparse matrix to place characters at specified positions
    }{5}