Tempdb is hard to shrink. Some pages cannot be moved because they are actively being used by system processes, so your chances of shrinking tempdb sink.
I see that you already have tried clearing all the caches, which sometimes helps, but is not guaranteed to work.
Try to identify what is using tempdb:
Even if usage is low, a single non movable page is enough to make the shrink process ineffective.
If you can't shrink it, I suggest that you plan a downtime to restart the service and let tempdb restart from its initial size.
Lists the TempDB usage per each active session.
It helps identifying the sessions that use the tempdb heavily with internal objects.
When the internal objects usage is high, the session is probably using big hash tables or spooling in worktables. It could be a symptom of
an inefficient plan or a missing index.
Shrinking a TempDB full of internal objects will probably have no effect, because the engine will not release the deallocated space.
The only possible alternative to restarting the service, is running DBCC FREESYSTEMCACHE('ALL'), that will clear all cached objects,
including not only internal objects, but also cached query plans. Use it carefully on a production server.
;WITH task_space_usage AS (
-- SUM alloc/delloc pages
SUM(internal_objects_alloc_page_count) AS alloc_pages,
SUM(internal_objects_dealloc_page_count) AS dealloc_pages
FROM sys.dm_db_task_space_usage WITH (NOLOCK)
WHERE session_id <> @@SPID
GROUP BY session_id, request_id
TSU.alloc_pages * 1.0 / 128 AS [internal object MB space],
TSU.dealloc_pages * 1.0 / 128 AS [internal object dealloc MB space],
-- Extract statement from sql text
ERQ.statement_start_offset / 2,
CASE WHEN ERQ.statement_end_offset < ERQ.statement_start_offset THEN 0 ELSE( ERQ.statement_end_offset - ERQ.statement_start_offset ) / 2 END
) AS [statement text],
FROM task_space_usage AS TSU
INNER JOIN sys.dm_exec_requests ERQ WITH (NOLOCK)
ON TSU.session_id = ERQ.session_id
AND TSU.request_id = ERQ.request_id
OUTER APPLY sys.dm_exec_sql_text(ERQ.sql_handle) AS EST
OUTER APPLY sys.dm_exec_query_plan(ERQ.plan_handle) AS EQP
WHERE EST.text IS NOT NULL OR EQP.query_plan IS NOT NULL
ORDER BY 3 DESC, 5 DESC