Board Rotation Problem - Best Practices
Overall I'd consider your approach to be "procedural" rather than object-oriented, which might have contributed to the feedback about "lack of best practices"

I agree with Shanif that it would be best to create a class with different methods and avoid static. 

Below is an example of the object-oriented approach. 

Under the principle of encapsulation I wondered, "Should the Board expose its inner workings of how it generates the moves?" I decided no, and kept the Board's "calculation" methods private. 

When I first posted this answer I knew that the various moves had enough in common to be candidates for inheritance. And, I got around to implementing it. Now the Move family of classes all derive from an abstract base class.

I also added the Solution class to capture the steps and help output them at the end.

Admittedly, this object model might be "overkill" for an app of this size. But, I was more interested in modeling the domain than in outputting the results as tersely as possible. 

Despite its verbosity in meeting the currently-modest requirements, this object model provides a foundation upon which the app could grow to any size.

Or, to put it another way... Object-oriented programming is useful for many things. Winning at code golf is not among them.

Here's the output:


And the code:  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class App_LetterBoard
{
    public void Run()
    {
        var board = new Board("agtcf");
        board.Solve("cat");
        board.OutputResult();

        Console.WriteLine();
        var board2 = new Board("agtcfqwerqweroqiweru");
        board2.Solve("cat");
        board2.OutputResult();
    }
}

public class Board
{
    private string initial; 
    private string target; 
    private string current; 
    private string result;
    private char next;

    public Solution Solution { get; private set; } = new Solution();

    public Board(string initial) =&gt; this.initial = initial;

    public void Solve(string target)
    {
        this.target = target;
        result = string.Empty;
        current = initial;            
        var index = 0;

        Solution.Add(new Start(initial));

        while (!result.Equals(target))
        {                
            next = target[index++];
            var distanceLeft = current.IndexOf(next);
            var distanceRight = current.Length - current.LastIndexOf(next) - 1;
            if (distanceLeft &lt;= distanceRight)
            {
                captureLeft(distanceLeft);
            }
            else
            {
                captureRight(distanceRight);
            };

            result = $"{result}{next}";
        }
    }

    public void OutputResult()
    {
        Console.WriteLine($"Find -&gt; {target}");
        Console.WriteLine(Solution.ToString());
    }

    private void captureRight(int distance)
    {
        for (var i = 0; i &lt; distance; i++)
        {
            var move = new RotateRight(current);
            Solution.Add(move);
            current = move.After;
        }

        var take = new TakeRight(current);
        Solution.Add(take);
        current = take.After;
    }

    private void captureLeft(int distance)
    {
        for (var i = 0; i &lt; distance; i++)
        {
            var move = new RotateLeft(current);
            Solution.Add(move);
            current = move.After;
        }

        var take = new TakeLeft(current);
        Solution.Add(take);
        current = take.After;
    }        
}

public class Solution
{
    public List&lt;Move&gt; Moves { get; private set; } = new List&lt;Move&gt;();

    public void Add(Move move) =&gt; Moves.Add(move);

    public override string ToString()
    {
        var sb = new StringBuilder();
        sb.AppendLine(string.Join("\n", Moves.Select(m =&gt; m.ToString())));
        return sb.ToString();
    }
}

public abstract class Move
{
    public abstract string Name { get; }

    public string Before { get; private set; }

    public string After =&gt; advance();

    public Move(string remaining) =&gt; Before = remaining;

    public override string ToString() =&gt; $"{Name} -&gt; {spread(After)}";

    protected abstract string advance();

    protected string removeLeft() =&gt; Before.Substring(1);

    protected string removeRight() =&gt; Before.Substring(0, Before.Length - 1);

    private string spread(string s) =&gt; string.Join(" ", s.ToArray());
}

public class Start : Move
{
    public override string Name =&gt; "Start";

    public Start(string current) : base(current) {}

    protected override string advance() =&gt; Before;
}

public class RotateLeft : Move
{
    public override string Name =&gt; "Rotate Left";

    public RotateLeft(string current) : base(current) { }

    protected override string advance() =&gt; $"{removeLeft()}{Before.First()}";
}

public class RotateRight : Move
{
    public override string Name =&gt; "Rotate Right";

    public RotateRight(string current) : base(current) { }

    protected override string advance() =&gt; $"{Before.Last()}{removeRight()}";
}

public abstract class Take : Move
{
    public override string Name =&gt; "Take";
    public Take(string current) : base(current) { }
}

public class TakeLeft : Take
{
    public TakeLeft(string current) : base(current) { }

    protected override string advance() =&gt; removeLeft();
}

public class TakeRight : Take
{
    public TakeRight(string current) : base(current) { }

    protected override string advance() =&gt; removeRight();
}