I assume you're doing the following.
1. You're opening a handle to the process you'll be injecting a DLL into.
2. You're remotely allocating memory into the targeted process through the VirtualAllocEx Win32 API routine (which in turn relies on NtAllocateVirtualMemory) which will be used to store the path of the module you'll be injecting into the targeted process.
3. You're remotely writing data to the memory you previously allocated through the WriteProcessMemory Win32 API routine (which in turn relies on NtWriteVirtualMemory) to actually store the path of the module you wish to inject into the targeted process.
4. You're creating a remote thread in the targeted process where the start address for the new thread is the address of LoadLibraryA (or LoadLibraryW if you're using a Unicode buffer) and the thread context is the address of the memory under the virtual address space of the targeted process which holds the path to the module you wish to inject (remember stages 2-3?).
Are my assumptions correct? It's a pretty common and well-known technique which has been supported since at-least Windows 2000 and it has been abused more than the amount of tree's that have been cut down in the world.
If my assumptions are correct, now that we've broken down the injection operation you're performing, there's some obvious traces:
1. There's a region of memory with at-least read access holding the path of the module you injected into the process.
2. There was a new thread which had a start address of the LoadLibraryA/W Win32 API routine which was valid under the context of the targeted process (otherwise the injection operation would have failed) and such can be tracked by someone if they really wanted to (e.g. monitor thread creation for the current process and log it).
3. There's an unknown module (your module) on the linked list for the loaded modules (can be found via the PEB).
4. There's an unknown module (your module) stored on an undocumented list which is setup by NTDLL (tracks all the modules which loaded on the current process's session - even if the module becomes unloaded it will stay on this undocumented list unlike the one which can be found via the PEB).
And... Wallah. Here we have even more traces.
1. Incorrect addresses (e.g. if you're patching the Import Address Table or Export Address Table) which can be identified by someone who knows what they are doing.
2. Incorrect instructions at the address of routines you're patching (e.g. if you're "hot patching" routines) which can be identified by someone who knows what they are doing.
3. You may be leaving incorrect memory access protection on areas you've changed the memory access protection of to gain write permissions (e.g. if you're doing #1, #2 or both).
4. You may be making a noticeable performance decrease due to your callback routines (e.g. someone who knows what they are doing may implement a timer-based system to check how long certain operations are taking and it may raise a red flag if the work you're doing on interception is slowing down the software and thus the timer is now a lot higher than it should be on the clock).
5. You may be causing crashes depending on what you're doing (e.g. buggy callback routines) and any crash logs which are reported back/checked may indicate that someone has been tampering dynamically.
Those are just to name a few.
And is there any way I could get rid of it?
Simple way is to avoid injecting code into other people's processes and then hooking APIs. That is the absolute best way to get rid of the traces... and to keep someone else's environment stable as it should be.
[Revoked the rest of the post].