Here's the script for the player's head : 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerScript : MonoBehaviour
{
    public bool isMoving;
    private Vector3 originPos, targetPos;
    public Vector3 lastDirection;
    public float moveTime = 0.15f;
    private float elapsedTime;

    public const float Vel = 9f;

    public List<Vector3> positionHistory = new List<Vector3>();
    public List<snakeBodyScript> bodySegments = new List<snakeBodyScript>();
    public List<Vector3> directionHistory = new List<Vector3>();

    public int moveCount;

    public GameObject bodyPrefab;

    void Update()
    {
        Move();

        SetBodyTarget();

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Grow();
        }
    }
    
    private void Move()
    {
        if (isMoving) return;

        if (Input.GetKey(KeyCode.W))
        {
            lastDirection = Vector3.up;
            StartCoroutine(MovePlayer(lastDirection));
            transform.rotation = Quaternion.Euler(0f, 0f, 0f);
 
        }
        else if (Input.GetKey(KeyCode.S))
        {
            lastDirection = Vector3.down;
            StartCoroutine(MovePlayer(lastDirection));
            transform.rotation = Quaternion.Euler(0f, 0f, 180f);

        }
        else if (Input.GetKey(KeyCode.A))
        {
            lastDirection = Vector3.left;
            StartCoroutine(MovePlayer(lastDirection));
            transform.rotation = Quaternion.Euler(0f, 0f, 90f);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            lastDirection = Vector3.right;
            StartCoroutine(MovePlayer(lastDirection));
            transform.rotation = Quaternion.Euler(0f, 0f, -90f);
        }
    }

    private IEnumerator MovePlayer(Vector3 direction)
    {
        isMoving = true;

        originPos = transform.position;
        targetPos = originPos + direction;
        directionHistory.Add(direction);
        elapsedTime = 0f;
        while (elapsedTime < moveTime)
        {
            transform.position = Vector3.Lerp(originPos, targetPos, elapsedTime / moveTime);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        transform.position = targetPos;

        isMoving = false;
    }

    private void SetBodyTarget()
    {
        if (bodySegments.Count > 0)
        {
            bodySegments[0].GetComponent<snakeBodyScript>().SetTargetPosition(transform.position);

            for (int index = bodySegments.Count - 1; index > 0; index --)
            {
                bodySegments[index].GetComponent<snakeBodyScript>().SetTargetPosition(bodySegments[index - 1].transform.position);
            }
        }
    }

    public void Grow()
    {
        if (positionHistory.Count == 0)
        {
            for (int i = 0; i < 3; i++)
                positionHistory.Add(transform.position);
        }

        Vector3 spawnPos = positionHistory[positionHistory.Count - 1];

        GameObject bodyPart = Instantiate(bodyPrefab, spawnPos, Quaternion.identity);
        snakeBodyScript bodyScript = bodyPart.GetComponent<snakeBodyScript>();
        bodyScript.player = this;

        bodySegments.Add(bodyScript);
    }
}

Here's the script for the body/tail :
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class snakeBodyScript : MonoBehaviour
{
    public playerScript player;
    private Vector3 nextBodyPos;
    private int waitPreviousParts;
    private int itemCount = 0;

    private void Start()
    {
        
    }

    private void Update()
    {
        if (player.bodySegments.Count > 0)
        {
            foreach (snakeBodyScript i in player.bodySegments)
            {
                if (player.bodySegments.Count == itemCount)
                {
                    itemCount = -1;
                }

                itemCount += 1;

                foreach (Vector3 v in player.directionHistory)
                {
                    player.bodySegments[itemCount].transform.position = Vector3.Lerp(transform.position, v, playerScript.Vel);
                }
            }
        }
    }

    public void WaitHeadUpdateCycle(int value)
    {
        waitPreviousParts = value;
    }
    
    public void SetTargetPosition(Vector3 targetPosition)
    {
        if (waitPreviousParts > 0)
        {
            waitPreviousParts--;
            return;
        }

        nextBodyPos = targetPosition;
    }
}