There are two main issues in your code; the one - as already mentioned in the comments - is that you do not increase pos but reassign it again and again with (almost) the same value. Hence, after the first iteration, you will constantly write to a position at 4 (or 5 if k would become >=10 and the numbers would thereby get more digits),
Second, your malloc will not work for small ks, since each string like "+1^2" takes at least 4 characters; so if you size the buffer with n * n,  then the buffer will be too small if n is <= 3, and (probably much) too big if n becomes larger.
I'd suggest to assume a maximum range of n (let's say up to 7 digits) and dimension the buffer accordingly.
A minor thing (and not essential) is that you probably could avoid writing superfluous + at all in that you use a different format string for the first iteration; just do show the idea, really not essential:
char* formatSeries(int n)
{
    const size_t maxSize = n * (7+3) + 1;
    char *tagstr = (char *)malloc(sizeof(char)*maxSize);
    int pos = 0 ;
    int k;
    for (k = 1; k <= n; k++)
    {
        const char* formatStr = (k==1) ? "%d^2" : "+%d^2";
        pos += sprintf(&tagstr[pos], formatStr, k);
    }
    return tagstr;
}