Recursive method to reverse Linked List I want to optimise this code and improve it using advanced C++.

#include &lt;iostream&gt;

template &lt;class T&gt;
class LinkedList
{
  struct Node
  {
    T data;
    Node * next;
    Node(T value) : data(value), next(nullptr) {}
  };
  Node *head;

public:
  LinkedList() : head(nullptr) {}
  ~LinkedList();
  void insert(T);
  void printList();
  void recursiveReverse()
  {
    Node *temp = head;
    head = recursiveReverse(temp);
  }
private:
  Node* recursiveReverse(Node* head)
  {
    if(head == nullptr)
      return nullptr;

    if(head-&gt;next == nullptr)
      return head;

    Node *firstElement = head;
    Node *secondElement = firstElement-&gt;next;
    head = firstElement-&gt;next;
    firstElement-&gt;next = nullptr; //unlink first node
    Node *remainingList = recursiveReverse(head);
    secondElement-&gt;next = firstElement;
    return remainingList;
  }
};

template &lt;class T&gt;
void LinkedList&lt;T&gt;::insert(T data)
{
  Node *node = new Node(data);
  Node *tmp = head;
  if(tmp == nullptr)
  {
    head = node;
  }
  else
  {
    while(tmp-&gt;next != nullptr)
    {
      tmp = tmp-&gt;next;
    }
    tmp-&gt;next = node;
  }
}

template &lt;class T&gt;
void LinkedList&lt;T&gt;::printList()
{
  Node *node = head;
  while(node)
  {
    std::cout &lt;&lt; node-&gt;data &lt;&lt; " ";
    node = node-&gt;next;
  }
  std::cout&lt;&lt;"\n";
}
template &lt;class T&gt;
LinkedList&lt;T&gt;::~LinkedList()
{
  Node *tmp = nullptr;
  while(head)
  {
    tmp = head;
    head = head-&gt;next;
    delete tmp;
  }
  head = nullptr;
}

int main()
{
  LinkedList&lt;int&gt; ll1;
  ll1.insert(2);
  ll1.insert(3);
  ll1.insert(4);
  ll1.insert(5);
  ll1.insert(6);
  ll1.printList();
  ll1.recursiveReverse();
  ll1.printList();
}
No warnings with very pedantic clang flags, good job! 


You have this in the destructor:

tmp = head;
head = head-&gt;next;
delete tmp;


You can replace this with a call to std::exchange:

delete std::exchange(head, head-&gt;next);

Use move semantics. Node::Node unnecessarily copies value into data. It should be data(std::move(value)) so that no copy is made. Same goes for LinkedList::insert and so on.
Single characters should be in single quotes, not double quotes. I won't claim it's more efficient, because any compiler worth its salt is going to optimize the call to std::strlen.
In LinkedList::recursiveReverse the first overload, you don't need to  copy head because the other overload you're calling isn't modifying its arguments (no pass by reference). You should also be able to merge both functions.
It might be "better" to keep a pointer to the last node in your linked list. That way, insertion is O(1) instead of O(n).
Mark functions that do not throw noexcept, if you compile with exceptions.
Mark classes that one shouldn't inherit from with final.
You could provide a constructor taking an std::initializer_list, so you could specify the elements of the list directly on construction.
Sometimes you use the implicit conversion to bool for pointers and sometimes not. It might be better to be consistent.
You can use in-class initializers for example for Node::next.
You can provide an iterator interface, so that your container works with the range for loop. For example, you can provide a public iterator, const_iterator alias to basically pointers to the individual elements inside nodes and provide begin and end as functions.
Please provide a copy and move constructor and assignment operator. This is known as the Rule of 5. If I copy your list, then I will probably get a double delete error at runtime, but this is not guaranteed.